package com.tvunetworks.center.device.service.rpc;

import com.fasterxml.jackson.databind.JsonNode;
import com.tvunetworks.center.common.constant.LocalConstant;
import com.tvunetworks.center.common.util.JsonUtil;
import com.tvunetworks.center.common.util.MyUtil;
import com.tvunetworks.center.device.util.AccessServerUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Etan Yang
 * @create: 2021/10/13 17:19
 */

@Slf4j
@Component
public class InstanceRpcService {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private AccessServerUtil accessServerUtil;

    @Value("${instance.addDomainRecord:http://10.12.22.93/instance/instance-manage/api/domain/addDomainRecord}")
    private String addDomainRecord;

    @Value("${instance.releaseDomainRecord:http://10.12.22.93/instance/instance-manage/api/domain/deleteByPeerId}")
    private String deleteDomainRecord;

    /**
     * 根据三级域名和ip去instance服务进行域名解析
     * @param tertiaryDomainName 三级域名
     * @param ip                 ip
     * @param version            version用来避免无限递归调用
     * @return 是否域名解析成功
     */
    public boolean getDomainByPeerIdAndIp(String tertiaryDomainName, String ip, int version) {
        try {
            //1.获取url
            String getDomainByPeerIdAndIpUrl = this.addDomainRecord;
            if (!StringUtils.startsWith(getDomainByPeerIdAndIpUrl, "http://")) {
                getDomainByPeerIdAndIpUrl = "http://" + getDomainByPeerIdAndIpUrl;
            }
            //2.获取请求头并将协议添加到请求头中
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add(LocalConstant.API_HEADER_PARAM_KEY, accessServerUtil.generatorAccess());
            Map<String, String> param = new HashMap<>();
            param.put("ip", ip);
            param.put("peerId", tertiaryDomainName);
            HttpEntity httpEntity = new HttpEntity(JsonUtil.toJsonStr(param), headers);

            ResponseEntity<String> responseEntity;
            log.error("Instance Service getDomainByPeerIdAndIp>>>>> url:{} pram:[{}]", getDomainByPeerIdAndIpUrl, param);
            try {
                responseEntity = restTemplate.postForEntity(getDomainByPeerIdAndIpUrl, httpEntity, String.class);
            } catch (RestClientException e) {
                log.error("Instance Service getDomainByPeerIdAndIp Http error url:{} pram:[{}]", getDomainByPeerIdAndIpUrl, param);
                return false;
            }

            if (responseEntity.getStatusCode() != HttpStatus.OK) {
                log.error("Instance Service getDomainByPeerIdAndIp HttpStatus not 200 url:{} pram:[{}] responseEntity:[{}]", getDomainByPeerIdAndIpUrl, param, responseEntity);
                return false;
            }
            String result = responseEntity.getBody();
            log.error("Instance Service getDomainByPeerIdAndIp HttpStatus result url:{} pram:[{}] result:[{}]", getDomainByPeerIdAndIpUrl, param, result);

            JsonNode jsonNode = MyUtil.MAPPER.readTree(result);
            if (!jsonNode.has("errorCode") || !("0x0".equalsIgnoreCase(jsonNode.get("errorCode").asText())
                    || "81204201".equalsIgnoreCase(jsonNode.get("errorCode").asText()))) {
                log.error("Instance Service getDomainByPeerIdAndIp HttpStatus result not success url:{} pram:[{}] result:[{}]", getDomainByPeerIdAndIpUrl, param, result);
                if (version == 2) {
                    log.error("Instance Service getDomainByPeerIdAndIp bind errorCode is error ip:[{}].domain:[{}],result:[{}]", ip, tertiaryDomainName, responseEntity);
                    return false;
                }
                this.releaseDomainByPeerId(tertiaryDomainName);
                Thread.sleep(200);
                return this.getDomainByPeerIdAndIp(tertiaryDomainName, ip, ++version);
            }
            return true;
        } catch (Exception e) {
            log.error("Instance Service getDomainByPeerIdAndIp exception,tertiaryDomainName:[{}],ip:[{}],exception:[{}]",
                    tertiaryDomainName, ip, e);
            return false;
        }
    }


    /**
     * 根据三级域名和ip去instance服务进行域名解析
     * @param tertiaryDomainName 三级域名
     * @return 是否域名解析成功
     */
    public boolean releaseDomainByPeerId(String tertiaryDomainName){
        try {
            //1.获取url
            String releaseDomainByPeerIdUrl = this.deleteDomainRecord;
            if (!StringUtils.startsWith(releaseDomainByPeerIdUrl, "http://")) {
                releaseDomainByPeerIdUrl = "http://" + releaseDomainByPeerIdUrl;
            }
            //2.获取请求头并将协议添加到请求头中
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add(LocalConstant.API_HEADER_PARAM_KEY, accessServerUtil.generatorAccess());
            Map<String, String> param = new HashMap<>();
            param.put("peerId", tertiaryDomainName);
            HttpEntity httpEntity = new HttpEntity(JsonUtil.toJsonStr(param), headers);

            ResponseEntity<String> responseEntity;
            log.error("Instance Service releaseDomainByPeerId >>>>> url:{} pram:[{}]", releaseDomainByPeerIdUrl, param);
            try {
                responseEntity = restTemplate.postForEntity(releaseDomainByPeerIdUrl, httpEntity, String.class);
            } catch (RestClientException e) {
                log.info("Instance Service releaseDomainByPeerId Http error url:{} pram:[{}]", releaseDomainByPeerIdUrl, param);
                return false;
            }

            if (responseEntity.getStatusCode() != HttpStatus.OK) {
                log.error("Instance Service releaseDomainByPeerId HttpStatus not 200 url:{} pram:[{}] responseEntity:[{}]", releaseDomainByPeerIdUrl, param, responseEntity);
                return false;
            }
            String result = responseEntity.getBody();
            log.error("Instance Service releaseDomainByPeerId HttpStatus result url:{} pram:[{}] result:[{}]", releaseDomainByPeerIdUrl, param, result);

            JsonNode jsonNode = MyUtil.MAPPER.readTree(result);
            if (!jsonNode.has("errorCode") || !("0x0".equalsIgnoreCase(jsonNode.get("errorCode").asText())
             || "81204203".equalsIgnoreCase(jsonNode.get("errorCode").asText()))) {
                log.error("Instance Service releaseDomainByPeerId HttpStatus result not success url:{} pram:[{}] result:[{}]", releaseDomainByPeerIdUrl, param, result);
                return false;
            }
            return true;
        } catch (IOException e) {
            log.error("Instance Service getDomainByPeerIdAndIp exception,tertiaryDomainName:[{}],exception:[{}]", tertiaryDomainName, e);
            return false;
        }
    }
}
